package com.fwtai.service.api;

import com.alibaba.fastjson2.JSONObject;
import com.fwtai.api.ApiBuyDao;
import com.fwtai.api.ApiUserBankDao;
import com.fwtai.api.ApiUserDao;
import com.fwtai.bean.PageFormData;
import com.fwtai.bean.UploadFile;
import com.fwtai.bean.UploadObject;
import com.fwtai.config.ConfigFile;
import com.fwtai.config.LocalUserId;
import com.fwtai.pay.wechat.ToolWechat;
import com.fwtai.pay.wechat.WechatPayConstants;
import com.fwtai.service.AsyncService;
import com.fwtai.service.core.MenuService;
import com.fwtai.service.core.UserService;
import com.fwtai.tool.IdBuilder;
import com.fwtai.tool.ToolClient;
import com.fwtai.tool.ToolCode;
import com.fwtai.tool.ToolJWT;
import com.fwtai.tool.ToolString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 系统用户业务层
 * @作者 田应平
 * @版本 v1.0
 * @QQ号码 444141300
 * @创建日期 2021-07-20 10:40:21
 * @官网 <url>http://www.fwtai.com</url>
 */
@Service
public class ApiUserService{

  private final AsyncService asyncService;

  private final CodeService codeService;

  private final ApiUserDao apiUserDao;

  private final UserService userService;

  private final MenuService menuService;

  private final ApiBuyDao apiBuyDao;

  private final ApiBuyService apiBuyService;

  private final ApiUserBankDao apiUserBankDao;

  private final ThreadPoolTaskExecutor taskExecutor;

  public ApiUserService(final AsyncService asyncService,final CodeService codeService,final ApiUserBankDao apiUserBankDao,final ApiUserDao apiUserDao,final ApiBuyService apiBuyService,final UserService userService,final MenuService menuService,final ApiBuyDao apiBuyDao,final ThreadPoolTaskExecutor taskExecutor){
    this.asyncService = asyncService;
    this.codeService = codeService;
    this.apiUserDao = apiUserDao;
    this.userService = userService;
    this.menuService = menuService;
    this.apiBuyDao = apiBuyDao;
    this.apiUserBankDao = apiUserBankDao;
    this.apiBuyService = apiBuyService;
    this.taskExecutor = taskExecutor;
  }

  @Value("${upload_dir_window}")
  private String dir_window;

  @Value("${upload_dir_linux}")
  private String dir_linux;

  public String add(final HttpServletRequest request){
    final PageFormData formData = new PageFormData().htmlEscape(request);
    final String p_user_name = "username";
    final String p_user_password = "user_password";
    final String p_verify_password = "verify_password";
    final String p_code = "code";
    final String validate = ToolClient.validateField(formData,p_user_password,p_verify_password,p_user_name,p_code);
    if(validate != null)return validate;
    final String user_password = formData.getString(p_user_password);
    final String verify_password = formData.getString(p_verify_password);
    if(user_password.length() < 6){
      return ToolClient.createJsonFail("密码长度必须大于5");
    }
    if(user_password.length() > 20){
      return ToolClient.createJsonFail("账号密码字数太长");
    }
    final String username = formData.getString(p_user_name);
    final boolean verifyPhone = ToolString.verifyPhone(username);
    if(!verifyPhone){
      return ToolClient.createJsonFail("手机号码有误");
    }
    if(username.length() > 20){
      return ToolClient.createJsonFail("登录账号字数太长");
    }
    if(!user_password.equals(verify_password)){
      return ToolClient.createJsonFail("输入的两次密码不一致");
    }
    final String code = formData.getString(p_code);
    formData.remove(p_code);//移除验证码
    formData.remove(p_user_password);//移除
    formData.remove(p_verify_password);//移除
    final String result = codeService.verify(username,code,true);
    if(result != null){
      return result;
    }
    final String kid = String.valueOf(new IdBuilder().getId121L());
    formData.put("kid",kid);
    final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    formData.put("password",encoder.encode(user_password));
    try {
      final int rows = apiUserDao.add(formData);
      if(rows > 0){
        return ToolClient.createJsonSuccess("恭喜,注册成功");
      }else {
        return ToolClient.createJsonFail("注册失败,稍候重试");
      }
    } catch (final Exception e) {
      return ToolClient.exceptionJson("该手机号已被注册了");
    }
  }

  public String edit(final HttpServletRequest request){
    final String loginId = LocalUserId.get();;
    if(loginId == null) return ToolClient.accessLogin();
    final PageFormData formData = new PageFormData().htmlEscape(request);
    final String p_real_name = "real_name";
    final String p_province_id = "province_id";
    final String p_province_name = "province_name";
    final String p_city_id = "city_id";
    final String p_city_name = "city_name";
    final String p_county_id = "county_id";
    final String p_county_name = "county_name";
    final String validate = ToolClient.validateField(formData,p_province_id,p_province_name,p_city_id,p_city_name,p_county_id,p_county_name,p_real_name);
    if(validate != null)return validate;
    if(formData.getString(p_real_name).length() > 10){
      return ToolClient.createJsonFail("真实姓名字数太长");
    }
    final String sex = formData.getString("sex");
    if(sex == null){
      formData.put("sex",3);
    }else{
      try {
        Integer.parseInt(sex);
      } catch (final Exception e) {
        return ToolClient.createJsonFail("性别有误");
      }
    }
    final String exist_key = apiUserDao.queryExistById(loginId);
    if(exist_key == null){
      return ToolClient.createJsonFail("数据不存在,刷新重试");
    }
    formData.put("loginId",loginId);
    final String address = formData.getString("address");
    if(address == null){
      formData.put("address","这家伙很懒,地址懒得写");
    }
    return ToolClient.executeRows(apiUserDao.edit(formData));
  }

  public String queryUserInfo(final String userId){
    if(userId == null || userId.length() <= 0){
      final String loginId = LocalUserId.get();
      if(loginId == null) return ToolClient.accessLogin();
      return ToolClient.queryJson(apiUserDao.queryUserInfo(loginId));
    }
    return ToolClient.queryJson(apiUserDao.queryUserInfo(userId));
  }

  public String queryInfoById(final String userId){
    if(userId == null || userId.length() <=0){
      return ToolClient.jsonValidateField();
    }
    final PageFormData formData = new PageFormData();
    final String loginId = LocalUserId.get();
    if(loginId != null){
      formData.put("loginId",LocalUserId.get());
    }
    formData.put("userId",userId);
    return ToolClient.queryJson(apiUserDao.queryInfoById(formData));
  }

  public String editPortrait(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    if(loginId == null) return ToolClient.accessLogin();
    final PageFormData formData = new PageFormData(request);
    final String baseDir = ToolString.isLinuxOS() ? dir_linux : dir_window;
    final UploadObject uploadObject = ToolClient.uploadFile(request,baseDir,"/law/portrait",false,1,3,true);
    final String errorMsg = uploadObject.getErrorMsg();
    if(errorMsg != null) return ToolClient.createJsonFail(errorMsg);
    final ArrayList<UploadFile> listFiles = uploadObject.getListFiles();
    if(listFiles == null || listFiles.size() <= 0) return ToolClient.createJsonFail("请选择上传图片");
    final UploadFile uploadFile = listFiles.get(0);
    final String fullPath = uploadFile.getFullPath();
    final String urlFile = uploadFile.getUrlFile();
    final HashMap<String,Object> map = apiUserDao.queryById(loginId);
    if(map == null){
      return ToolClient.createJson(ConfigFile.code198,"请先完善个人信息");
    }
    formData.put("loginId",loginId);
    formData.put("img_path",fullPath);
    formData.put("portrait",urlFile);
    final int rows = apiUserDao.editPortrait(formData);
    if(rows > 0){
      final HashMap<String,String> result = new HashMap<>();
      result.put("portrait",urlFile);
      result.put(ConfigFile.record,String.valueOf(rows));
      return ToolClient.queryJson(result);
    }else{
      return ToolClient.executeRows(rows);
    }
  }

  public String addPartner(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = new PageFormData(request);
      final String p_real_name = "real_name";
      final String p_type = "type";
      final String p_province_id = "province_id";
      final String p_province_name = "province_name";
      final String p_city_id = "city_id";
      final String p_city_name = "city_name";
      final String p_county_id = "county_id";
      final String p_county_name = "county_name";
      final String p_phone = "phone";
      final String p_details = "details";
      final String validate = ToolClient.validateField(formData,p_province_id,p_province_name,p_city_id,p_city_name,p_county_id,p_county_name,p_phone,p_details,p_real_name,p_type);
      if(validate != null){
        return validate;
      }
      final String fieldInteger = ToolClient.validateInteger(formData,p_type);
      if(fieldInteger != null)return fieldInteger;
      final Integer type = formData.getInteger(p_type);
      final long loginKey = Long.parseLong(loginId);
      final HashMap<String,Object> referrer = apiUserDao.getReferrer(loginKey);
      if(referrer != null){
        final Integer referrerType = (Integer) referrer.get("type");
        switch (referrerType){
          case 1:
            return ToolClient.createJsonFail("您已申请为"+referrer.get("province_name")+"的省分公司");
          case 2:
            return ToolClient.createJsonFail("您已申请为"+referrer.get("city_name")+"的市分公司");
          case 3:
            return ToolClient.createJsonFail("您已申请为"+referrer.get("county_name")+"的区代理");
          default:
            break;
        }
      }
      formData.put("loginId",loginKey);
      final Long kid = new IdBuilder().getId121L();
      formData.put("kid",kid);
    /*
      省分公司可以推广市分公司和区级代理；
      市级分公司可以推广区级代理；
      区级代理可以推广多个直营门店；
    */
      final Long provinceId = formData.getLong(p_province_id);
      final Long cityId = formData.getLong(p_city_id);
      final Long countyId = formData.getLong(p_county_id);
      switch (type){
        case 1:
          final boolean type1 = apiUserDao.getProxyType(provinceId);
          if(type1){
            return ToolClient.createJsonFail("您申请的省分公司已被Ta人申请");
          }
          break;
        case 2:
          final boolean type2 = apiUserDao.getProxyType(provinceId,cityId);
          if(type2){
            return ToolClient.createJsonFail("您申请的市分公司已被Ta人申请");
          }
          break;
        case 3:
          final boolean type3 = apiUserDao.getProxyType(provinceId,cityId,countyId);
          if(type3){
            return ToolClient.createJsonFail("您申请的区代理已被Ta人申请");
          }
          break;
        default:
          break;
      }
      final String inviteCode = formData.getString("code");//邀请码
      if(inviteCode != null){
        formData.put("code",inviteCode);
      }
      final String recommendCode = formData.getString("recommend_code");//邀请码
      if(recommendCode != null){
        formData.put("referrer",apiUserDao.getUserIdByCode(recommendCode));
      }
      return ToolClient.executeRows(apiUserDao.addPartner(formData));
    },taskExecutor).join();
  }

  //计算从业年限
  private void compute(final List<Map<String,Object>> list){
    list.forEach(item->{
      final String date = (String)item.get("practice_date");
      final String realName = (String)item.get("real_name");
      final LocalDate start = LocalDate.now();
      final LocalDate end = LocalDate.parse(date);
      final int years = Period.between(end,start).getYears();
      final int len = realName.length();
      switch (len){
        case 1:
          break;
        case 2:
          item.put("real_name",realName.charAt(0)+"*");
          break;
        default:
          final String sub = realName.substring(1,2);
          item.put("real_name",realName.replaceFirst(sub,"*"));
          break;
      }
      item.put("practice_date",years);
    });
  }

  public String updatePassword(final PageFormData formData){
    final String loginId = LocalUserId.get();
    if(loginId == null) return ToolClient.accessLogin();
    return userService.editPassword(formData);
  }

  public String updateForget(final PageFormData formData){
    final String p_phone = "phone";
    final String p_code = "code";
    final String p_password = "password";
    final String p_verify = "verify";
    final String validate = ToolClient.validateField(formData,p_phone,p_code,p_password,p_verify);
    if(validate != null)return validate;
    final String code = formData.getString(p_code);
    final String phone = formData.getString(p_phone);
    final String password = formData.getString(p_password);
    final String verify = formData.getString(p_verify);
    final boolean verifyPhone = ToolString.verifyPhone(phone);
    if(!verifyPhone){
      return ToolClient.createJsonFail("手机号码有误");
    }
    if(!verify.equals(password)){
      return ToolClient.createJsonFail("输入的两次密码不一致");
    }
    final HashMap<String,Object> hashMap = apiUserDao.queryUser(phone);
    if(hashMap == null){
      return ToolClient.createJsonFail("您的手机号尚未注册");
    }
    final Integer enabled = (Integer) hashMap.get("enabled");
    if(enabled == 1){
      return ToolClient.createJsonFail("账号已被禁用");
    }
    final String result = codeService.verify(phone,code,true);
    if(result != null){
      return result;
    }
    return userService.updateForget(formData,password);
  }

  public String getInfo(final String code){
    if(code == null || code.length() <= 0){
      return ToolClient.jsonValidateField();
    }
    final JSONObject wechatInfo = ToolWechat.getWechatInfo(code,WechatPayConstants.APP_ID,WechatPayConstants.SECRET);
    if(wechatInfo == null){
      return ToolClient.createJsonFail("微信通讯失败");
    }
    if(wechatInfo.containsKey("errcode")){
      return ToolClient.createJsonFail("无效的微信code");
    }
    return ToolClient.queryJson(wechatInfo);
  }

  public String bindPhone(final PageFormData formData){
    final String p_phone = "phone";
    final String smsCode = "smsCode";//短信验证码
    final String p_openId = "openId";//微信code
    final String validate = ToolClient.validateField(formData,p_phone,smsCode,p_openId);
    if(validate != null)return validate;
    final String phone = formData.getString(p_phone);
    final boolean verifyPhone = ToolString.verifyPhone(phone);
    if(!verifyPhone){
      return ToolClient.createJsonFail("手机号码有误");
    }
    final String result = codeService.verify(phone,formData.getString(smsCode),true);
    if(result != null){
      return result;
    }
    final String openid = formData.getString(p_openId);
    final HashMap<String,Object> hashMap = apiUserDao.queryUser(phone);
    if(hashMap == null){//注册,初始化(若手机号还未注册时会自动注册并登录)
      final PageFormData params = new PageFormData();
      final String kid = String.valueOf(new IdBuilder().getId121L());
      params.put("kid",kid);
      params.put("password","www.fwtai.com");
      params.put("username",phone);
      params.put("wx_openid",openid);
      final int rows = apiUserDao.add(params);
      if(rows > 0){
        final HashMap<String,Object> map = new HashMap<>(1);
        map.put(ConfigFile.ACCESS_TOKEN,ToolJWT.buildAccessToken(kid));
        return ToolClient.queryJson(map);
      }else {
        return ToolClient.createJsonFail("操作失败,稍候重试");
      }
    }else{//返回token
      final Integer enabled = (Integer) hashMap.get("enabled");
      if(enabled == 1){
        return ToolClient.createJsonFail("账号已被禁用");
      }
      asyncService.updateWechat(formData);
      final HashMap<String,Object> map = new HashMap<>(2);
      final Integer t = (Integer) hashMap.get("type");
      if(t != null){
        final HashMap<String,Object> info = new HashMap<>(5);
        info.put("type",t);
        info.put("realName",hashMap.get("real_name"));
        info.put("phone",hashMap.get("phone"));
        info.put("address",hashMap.get("address"));
        info.put("portrait",hashMap.get("portrait"));
        map.put("info",info);
      }
      map.put(ConfigFile.ACCESS_TOKEN,ToolJWT.buildAccessToken(String.valueOf(hashMap.get("kid"))));
      asyncService.updateLogin(phone);
      return ToolClient.queryJson(map);
    }
  }

  /**更换手机号码*/
  public String updatePhone(final String phone,final String code,final String verify){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null) return ToolClient.accessLogin();
      if(phone == null){
        return ToolClient.jsonValidateField();
      }
      if(verify == null){//为空时说明是准备绑定手机号
        if(code == null){
          return ToolClient.createJsonFail("请输入验证码");
        }else{
          final String result = codeService.verify(phone,code,false);
          if(result != null){
            return result;
          }
          final HashMap<String,Object> hashMap = apiUserDao.queryUser(phone);
          if(hashMap != null){
            return ToolClient.json198(hashMap.get("real_name"));//仅返回昵称
          }
          return handlerResult(loginId,phone,1,null);
        }
      }else{//不为空时说明是code=198继续绑定
        return handlerResult(loginId,phone,2,code);
      }
    },taskExecutor).join();
  }

  private String handlerResult(final long loginId,final String phone,final int target,final String code){
    final PageFormData formData = new PageFormData(3);
    formData.put("loginId",loginId);
    formData.put("phone",phone);
    switch (target){
      case 1:
        return ToolClient.executeRows(apiUserDao.updatePhone(formData),"更换成功","更换失败,稍候重试");
      case 2://验证手机号和验证码是否有效
        final String result = codeService.verify(phone,code,true);
        if(result != null){
          return result;
        }
        formData.put("oldPhone",ToolCode.displacePhone());
        return ToolClient.executeRows(apiUserDao.editVerifyPhone(formData),"更换成功","更换失败,稍候重试");
      default:
        return ToolClient.jsonValidateField();
    }
  }

  //参考，final
  public String updateOpenid(final String code){
    final String loginId = LocalUserId.get();
    if(loginId == null) return ToolClient.accessLogin();
    if(code == null || code.length() <=0){
      return ToolClient.createJsonFail("微信code有误");
    }
    final JSONObject jsonObject = ToolWechat.getWechatInfo(code,WechatPayConstants.APP_ID,WechatPayConstants.SECRET);
    if(jsonObject == null){
      return ToolClient.createJsonFail("微信通讯失败");
    }
    if(jsonObject.containsKey("errcode")){
      return ToolClient.createJsonFail("无效的微信code");
    }
    final Integer enabled = apiUserDao.queryUserById(loginId);
    if(enabled == 1){
      return ToolClient.createJsonFail("您的账号已被禁用");
    }
    final String openid = jsonObject.getString("openid");//session_key
    final PageFormData formData = new PageFormData();
    formData.put("openid",openid);
    formData.put("loginId",loginId);
    try {
      final CompletableFuture<Integer> async = CompletableFuture.supplyAsync(() -> {
        return apiUserDao.updateOpenid(formData);
      },taskExecutor);
      return ToolClient.executeRows(async.get(),"更换成功","更换失败,稍候重试");
    } catch (final Exception e) {
      return ToolClient.exceptionJson(ConfigFile.msg204);
    }
  }

  public String login(final String code){
    if(code == null || code.length() <= 0){
      return ToolClient.jsonValidateField();
    }
    final JSONObject wechatInfo = ToolWechat.getWechatInfo(code,WechatPayConstants.APP_ID,WechatPayConstants.SECRET);
    if(wechatInfo == null){
      return ToolClient.createJsonFail("微信通讯失败");
    }
    if(wechatInfo.containsKey("errcode")){
      return ToolClient.createJsonFail("无效的微信code");
    }
    final String openId = wechatInfo.getString("openid");
    final HashMap<String,Object> exist = apiUserDao.queryOpenid(openId);
    if(exist == null){//未绑定
      return ToolClient.wechat(openId);
    }else{//已绑定,需返回token信息
      final Integer enabled = (Integer) exist.get("enabled");
      if(enabled == 1){
        return ToolClient.createJsonFail("账号已被禁用");
      }
      final HashMap<String,Object> map = new HashMap<>(2);
      final HashMap<String,Object> hashMap = menuService.queryUser(String.valueOf(exist.get("user_name")));
      if(hashMap != null){
        final Integer t = (Integer) hashMap.get("type");
        if(t != null){
          final HashMap<String,Object> info = new HashMap<>(5);
          info.put("type",t);
          info.put("realName",hashMap.get("real_name"));
          info.put("phone",hashMap.get("phone"));
          info.put("address",hashMap.get("address"));
          info.put("portrait",hashMap.get("portrait"));
          map.put("info",info);
        }
      }
      map.put(ConfigFile.ACCESS_TOKEN,ToolJWT.buildAccessToken(String.valueOf(exist.get("kid"))));
      asyncService.updateLogin(String.valueOf(exist.get("user_name")));
      return ToolClient.queryJson(map);
    }
  }

  //获取手机号
  public String getWechatPhone(final String code){
    if(code == null || code.length() <= 0){
      return ToolClient.jsonValidateField();
    }
    final JSONObject json = ToolWechat.getPhoneNumber(code,WechatPayConstants.APP_ID,WechatPayConstants.SECRET);
    if(json == null){
      return ToolClient.createJsonFail("微信通讯失败");
    }
    if(json.containsKey("errcode")){
      final Integer errcode = json.getInteger("errcode");
      if(errcode != 0){
        return ToolClient.createJsonFail("服务繁忙,稍候重试");
      }
    }
    final JSONObject phoneInfo = json.getJSONObject("phone_info");
    final HashMap<String,String> map = new HashMap<>();
    map.put("phoneNumber",phoneInfo.getString("phoneNumber"));
    map.put("purePhoneNumber",phoneInfo.getString("purePhoneNumber"));
    map.put("countryCode",phoneInfo.getString("countryCode"));
    return ToolClient.queryJson(map);
  }

  // 注册走的是携法网的接口，购票走的是论坛的接口,此时独立程序开发了、
  public String signIn(final HttpServletRequest request){
    final PageFormData formData = new PageFormData(request);
    final String p_codeOpenId = "codeOpenId";
    final String p_codePhone = "codePhone";
    final String validate = ToolClient.validateField(formData,p_codeOpenId,p_codePhone);
    if(validate != null)return validate;
    final String appId = WechatPayConstants.APP_ID;
    final String secret = WechatPayConstants.SECRET;
    final JSONObject wechatInfo = ToolWechat.getWechatInfo(formData.getString(p_codeOpenId),appId,secret);
    if(wechatInfo == null){
      return ToolClient.createJsonFail("微信通讯失败");
    }
    if(wechatInfo.containsKey("errcode")){
      return ToolClient.createJsonFail("无效的微信code");
    }
    final String openId = wechatInfo.getString("openid");
    final JSONObject json = ToolWechat.getPhoneNumber(formData.getString(p_codePhone),appId,secret);//获取手机号码
    if(json == null){
      return ToolClient.createJsonFail("微信通讯失败");
    }
    if(json.containsKey("errcode")){
      final Integer errcode = json.getInteger("errcode");//40029,可能刚才说话说的太久了，code失效导致的。
      if(errcode != 0){
        return ToolClient.createJsonFail("服务繁忙,稍候重试");
      }
    }
    final JSONObject phoneInfo = json.getJSONObject("phone_info");
    final String phone = phoneInfo.getString("purePhoneNumber");
    final HashMap<String,Object> hashMap = apiUserDao.queryUser(phone);
    if(hashMap == null){
      formData.put("sex",3);
      //1.注册,个人资料
      final long id = new IdBuilder().getId121L();
      final String kid = String.valueOf(id);
      formData.put("real_name","微信用户"+openId.substring(openId.length() - 5));
      formData.put("kid",kid);//sys_user和share_relation共用的key
      formData.put("password","www.fwtai.com");
      formData.put("username",phone);
      formData.put("wx_openid",openId);
      final int rows = apiUserDao.addWechat(formData,id);
      return handlerRows(kid,rows,phone);
    }else{
      final Integer enabled = (Integer) hashMap.get("enabled");
      if(enabled == 1){
        return ToolClient.createJsonFail("账号已被禁用");
      }
      asyncService.updateWechat(formData);//处理注册,下面的处理登录
      final HashMap<String,Object> map = new HashMap<>(2);
      map.put("info",handlerInfo(hashMap,phone));
      map.put(ConfigFile.ACCESS_TOKEN,ToolJWT.buildAccessToken(String.valueOf(hashMap.get("kid"))));
      asyncService.updateLogin(phone);
      return ToolClient.queryJson(map);
    }
  }

  HashMap<String,Object> handlerInfo(final HashMap<String,Object> hashMap,final String phone){
    final HashMap<String,Object> info = new HashMap<>(7);
    info.put("realName",hashMap.get("real_name"));
    info.put("category",hashMap.get("category"));
    info.put("phone",hashMap.get("phone"));
    info.put("address",hashMap.get("address"));
    info.put("portrait",hashMap.get("portrait"));
    info.put("username",phone);
    final Object t = hashMap.get("agentType");//是代理商级别或门店店主
    if(t != null){
      info.put("type",t);
    }
    return info;
  }

  private String handlerRows(final String kid,final int rows,final String phone){
    if(rows > 0){
      final HashMap<String,Object> map = new HashMap<>(2);
      map.put(ConfigFile.ACCESS_TOKEN,ToolJWT.buildAccessToken(kid));
      map.put("info",handlerInfo(apiUserDao.queryUser(phone),phone));
      return ToolClient.queryJson(map);
    }else {
      return ToolClient.createJsonFail("操作失败,稍候重试");
    }
  }

  public String getUserOptions(){
    final String loginId = LocalUserId.get();
    if(loginId == null) return ToolClient.accessLogin();
    return ToolClient.queryJson(apiUserDao.getUserOptions(loginId));
  }

  public String getNonPayment(){
    final String loginId = LocalUserId.get();
    if(loginId == null){
      return ToolClient.accessLogin();
    }
    return ToolClient.queryJson(apiUserDao.getNonPayment(loginId));
  }

  //通过邀请码查看邀请人信息
  public String getInviteInfo(final String code){
    if(code == null){
      return ToolClient.jsonValidateField();
    }
    final HashMap<String,Object> map = apiUserDao.getInviteInfo(code);
    return ToolClient.queryJson(map);
  }

  //获取申请审核情况
  public String getUserAuthInfo(){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final long userId = Long.parseLong(loginId);
      HashMap<String,Object> authStatus = apiUserDao.getUserAuthInfo(userId);
      final Integer category = apiUserDao.getCategory(userId);
      if(authStatus == null){
        authStatus = new HashMap<>();
      }
      authStatus.put("category",category);
      return ToolClient.queryJson(authStatus);
    },taskExecutor).join();
  }

  public String getMySecurities(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request,"status");
      if(formData == null) return ToolClient.jsonValidateField();
      formData.put("loginId",loginId);
      final Integer status = formData.getInteger("status");
      if(status == 3){
        formData.remove("status");
        formData.put("invalid",status);
        return ToolClient.jsonPage(apiUserDao.getMySecurities(formData));
      }
      return ToolClient.jsonPage(apiUserDao.getMySecurities(formData));
    },taskExecutor).join();
  }

  public String listReferrerUser(final HttpServletRequest request){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request);
      if(formData == null) return ToolClient.jsonValidateField();
      formData.put("loginId",loginId);
      final List<HashMap<String,Object>> list = apiUserDao.listReferrerUser(formData);
      list.forEach(map -> {
        final Long referrer = (Long)map.get("referrer");
        if(!loginId.equals(referrer)){
          map.put("change",1);
        }
        map.put("user_name",ToolString.replacePhone((String) map.get("user_name")));//处理数据脱敏
      });
      return ToolClient.jsonPage(list);
    },taskExecutor).join();
  }

  public String getIntegralAccount(){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      //已结算，未结算,总额
      final HashMap<String,Object> result = new HashMap<>(2);
      final BigDecimal total = apiUserDao.getIntegralAccount(loginId);//总额
      final List<HashMap<String,Object>> applyAccount = apiUserDao.getApplyAccount(loginId);
      final List<HashMap<String,Object>> accountIn = apiUserDao.getAccountIn(loginId);
      result.put("total",total);
      result.put("apply",applyAccount);
      result.put("account",accountIn);
      return ToolClient.queryJson(result);
    },taskExecutor).join();
  }

  public String getReferrerAccount(){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final Integer totalMember = apiUserDao.getReferrerAccount(loginId);
      final BigDecimal totalIncome = apiUserDao.getReferrerAllIncome(loginId);
      final HashMap<String,Object> result = new HashMap<>(2);
      result.put("totalMember",totalMember);
      result.put("totalIncome",totalIncome);
      return ToolClient.queryJson(result);
    },taskExecutor).join();
  }

  public String getStoreSecurities(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request,"status");
      if(formData == null) return ToolClient.jsonValidateField();
      formData.put("loginId",loginId);
      final Integer status = formData.getInteger("status");
      if(status == 3){
        formData.remove("status");
        formData.put("invalid",status);
        return ToolClient.jsonPage(apiUserDao.getStoreSecurities(formData));
      }
      return ToolClient.jsonPage(apiUserDao.getStoreSecurities(formData));
    },taskExecutor).join();
  }

  public String getApplyRecord(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request);
      if(formData == null) return ToolClient.jsonValidateField();
      formData.put("loginId",Long.parseLong(loginId));
      return ToolClient.jsonPage(apiUserDao.getApplyRecord(formData));
    },taskExecutor).join();
  }

  public String listIntegral(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request);
      if(formData == null) return ToolClient.jsonValidateField();
      final Integer enabled = formData.getInteger("enabled");
      if(enabled != null){
        switch (enabled){
          case 0:
            break;
          case 1:
            break;
          default:
            return ToolClient.jsonValidateField();
        }
      }
      formData.put("loginId",Long.parseLong(loginId));
      return ToolClient.jsonPage(apiUserDao.listIntegral(formData));
    },taskExecutor).join();
  }

  public String getSecuritiesById(final String kid){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null) return ToolClient.tokenInvalid();
      if(kid == null || kid.length() == 0) ToolClient.jsonValidateField();
      final HashMap<String,Object> map = apiUserDao.getOrderSecurities(Long.parseLong(kid));
      map.put("user_name",ToolString.replacePhone((String) map.get("user_name")));//处理数据脱敏
      return ToolClient.queryJson(map);
    },taskExecutor).join();
  }

  public String getSecuritiesOrder(final Long kid){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null) return ToolClient.tokenInvalid();
      if(kid == null) ToolClient.jsonValidateField();
      final HashMap<String,Object> map = apiUserDao.getSecuritiesOrder(kid);
      final List<HashMap<String,Object>> list = apiUserDao.getOrderDetail(kid);
      final HashMap<String,Object> result = new HashMap<>(2);
      result.put("info",map);
      result.put("list",list);
      return ToolClient.queryJson(result);
    },taskExecutor).join();
  }

  //店主确认核销优惠券
  public String verifySecurities(final String kid){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null) return ToolClient.tokenInvalid();
      if(kid == null || kid.length() == 0) ToolClient.jsonValidateField();
      final long id = Long.parseLong(kid);
      final HashMap<String,Object> securities = apiUserDao.getSecurities(id);
      if(securities == null){
        return ToolClient.createJsonFail("优惠券信息已不存在");
      }
      final Integer state = (Integer)securities.get("status");//优惠券状态（1未核销，2已核销）
      if(state == 2){
        return ToolClient.createJsonFail("优惠券已核销");
      }
      final Long start = (Long)securities.get("start");
      if(start < 0){
        return ToolClient.createJsonFail("优惠券未到使用时间");
      }
      final Long conclude = (Long)securities.get("conclude");
      if(conclude < 0){
        return ToolClient.createJsonFail("优惠券已过期");
      }
      final HashMap<String,Object> params = new HashMap<>(2);
      params.put("loginId",loginId);
      params.put("kid",id);
      final Integer cargoStatus = apiUserDao.getOrderCargo(id);
      if(cargoStatus != 2){
        return ToolClient.createJsonFail("订单尚未确认收货,请先确认收货");
      }
      final int rows = apiUserDao.editSecurities(params);
      if(rows > 0){//核销成功时添加优惠券积分
        verifySecurities(id);//按订单核销优惠券
      }
      return ToolClient.executeRows(rows,"兑换成功","兑换失败");
    },taskExecutor).join();
  }

  private BigDecimal handlerLevelIntegral(final HashMap<Long,HashMap<Integer,BigDecimal>> map,final Integer level){
    BigDecimal value = new BigDecimal("0.00");//已支持购物车积分计算
    for(final Long key : map.keySet()){
      value = value.add(map.get(key).get(level));
    }
    return value;
  }

  //按订单核销优惠券,消费者不能使用积分支付
  public void verifySecurities(final long id){
    //查询订单的积分
    final HashMap<String, Object> OutTradeNoUserId = apiBuyDao.getOutTradeNoUserId(id);
    final long outTradeNo = (Long) OutTradeNoUserId.get("out_trade_no");
    final Long store_user = (Long) OutTradeNoUserId.get("store_user");
    final List<HashMap<String,Object>> goodsIntegrals = apiBuyDao.getGoodsIntegral(outTradeNo);//获取订单的商品的对应的不同等级的积分数
    final HashMap<Long,HashMap<Integer,BigDecimal>> mapIntegral = apiBuyService.handlerIntegral(goodsIntegrals,"discounts");//优惠卷积分

    //门店开始
    final HashMap<String,Object> mapDiscounts = new HashMap<>(8);
    mapDiscounts.put("user_id",OutTradeNoUserId.get("store_user"));
    mapDiscounts.put("score",handlerLevelIntegral(mapIntegral,4));
    mapDiscounts.put("type",4);
    mapDiscounts.put("kid",new IdBuilder().getId121L());
    mapDiscounts.put("category",3);
    mapDiscounts.put("out_trade_no",outTradeNo);
    //是否已收货则结算积分 enabled = 1,否则 enabled = 0
    final Integer cargoStatus = apiBuyDao.getCargoStatus(outTradeNo);
    final long clearing_date = System.currentTimeMillis() / 1000;
    final List<HashMap<String,Object>> listDiscounts = new ArrayList<>(1);
    if(cargoStatus == 2){
      mapDiscounts.put("enabled",1);
      mapDiscounts.put("clearing_date",clearing_date);
      listDiscounts.add(mapDiscounts);
      apiUserDao.addAccountDiscounts(mapDiscounts,listDiscounts);
    }else{
      listDiscounts.add(mapDiscounts);
      apiUserDao.addAccountDiscounts(listDiscounts);
    }
    //门店结束

    //区级、市级、省级
    final ArrayList<HashMap<String,Object>> listData = new ArrayList<>(goodsIntegrals.size());

    final List<HashMap<String,Object>> proxyExist = apiBuyDao.getProxyExist(store_user);//user_id是直营门店的店主
    for(int i = proxyExist.size() - 1; i >= 0; i--){
      final HashMap<String,Object> hashMap = proxyExist.get(i);//user_id
      final HashMap<String,Object> mapData = new HashMap<>(4);
      mapData.put("user_id",hashMap.get("user_id"));//上级代理
      final Integer type = (Integer) hashMap.get("type");
      mapData.put("type",hashMap.get("type"));
      mapData.put("score",handlerLevelIntegral(mapIntegral,type));
      listData.add(mapData);
    }

    final ArrayList<HashMap<String,Object>> listParams = new ArrayList<>(goodsIntegrals.size());
    final Map<Long,List<Map<String,Object>>> objGetMap = apiBuyService.listObjGetMap(listData,"user_id");//以user_id分组
    objGetMap.forEach((k,lists)->{
      final HashMap<String,Object> tempMap = new HashMap<>(8);
      tempMap.put("user_id",k);
      tempMap.put("kid",new IdBuilder().getId121L());
      BigDecimal totalValue = new BigDecimal(0);//计算总积分
      for(int i = lists.size() - 1; i >= 0; i--){
        final Map<String,Object> objectMap = lists.get(i);
        tempMap.put("out_trade_no",outTradeNo);
        totalValue = totalValue.add((BigDecimal) objectMap.get("score"));
        tempMap.put("type",objectMap.get("type"));
      }
      tempMap.put("score",totalValue);
      tempMap.put("category",3);
      if(cargoStatus == 2){
        tempMap.put("enabled",1);
        tempMap.put("clearing_date",clearing_date);
        mapDiscounts.put("enabled",1);
        mapDiscounts.put("clearing_date",clearing_date);
      }
      listParams.add(tempMap);
    });

    final BigDecimal vipDiscounts = handlerLevelIntegral(mapIntegral,1);//获取事业部用户的积分
    final HashMap<Long,HashMap<Integer,BigDecimal>> mapIntegrals = apiBuyService.handlerIntegral(goodsIntegrals,"scores");//推荐人的优惠券积分数
    final BigDecimal referrerValue = handlerLevelIntegral(mapIntegrals,5);//获取推荐人的积分
    final ArrayList<Long> users = new ArrayList<>(3);
    for(int x = proxyExist.size() - 1; x >= 0; x--){
      final Long referrer = (Long) proxyExist.get(x).get("referrer");
      if(referrer != null){
        users.add(referrer);
      }
    }
    final List<Long> vipUser = users.size() > 0 ? apiBuyDao.getVipUser(users) : null;
    final ArrayList<HashMap<String,Object>> listVipUser = new ArrayList<>(goodsIntegrals.size());
    proxyExist.forEach(mapRemove->{
      if(mapRemove.containsKey("referrer")){//仅过滤存在推荐人,如果存在推荐人再判断是否是事业部用户,如果是则按省级分公司的分成(含佣金和优惠卷分成)
        mapRemove.put("kid",new IdBuilder().getId121L());
        mapRemove.put("out_trade_no",outTradeNo);
        final long referrer = (Long) mapRemove.get("referrer");
        mapRemove.put("referrerValue",apiBuyService.checkVip(vipUser,referrer) ? vipDiscounts : referrerValue);
        mapRemove.put("type",apiBuyService.checkVip(vipUser,referrer) ? 6 : 5);
        mapRemove.put("category",4);
        listVipUser.add(mapRemove);
      }
    });
    if(listVipUser.size() > 0){
      if(cargoStatus == 2){
        listVipUser.forEach(map -> {
          map.put("score",map.get("referrerValue"));
          map.put("enabled",1);
          map.put("clearing_date",clearing_date);
        });
        apiUserDao.addReferrerSource(listVipUser);//添加推荐人积分|核销时插入推荐人或事业部积分
      }else{
        listVipUser.forEach(map -> {
          map.put("user_id",map.get("referrer"));
          map.put("score",map.get("referrerValue"));
        });
        apiUserDao.addAccountDiscounts(listVipUser);//推荐积分
      }
    }
    if(cargoStatus == 2){
      apiUserDao.addAccountIn(listParams);
    }else{
      apiUserDao.addAccountDiscounts(listParams);
    }
  }

  public String addUserAccountOut(final String value){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null) return ToolClient.tokenInvalid();
      if(value == null || value.length() == 0) ToolClient.jsonValidateField();
      final BigDecimal decimal = new BigDecimal(value);//申请总额
      if(!(decimal.floatValue() >= 100.00)){
        return ToolClient.createJsonFail("积分不能小于100");
      }
      final HashMap<String,Object> record = apiUserDao.getAccountInfo(loginId);
      final Integer enabled = (Integer)record.get("enabled");
      if(1 == enabled){
        return ToolClient.createJsonFail("您的账户已被冻结");
      }
      final BigDecimal score = (BigDecimal)record.get("score");//账户上的总额
      if(decimal.compareTo(score) > 0){
        return ToolClient.createJsonFail("兑换失败,积分不足");
      }
      final BigDecimal records = apiUserDao.getApplyRecordTotal(loginId);//未兑换的
      if(records != null){
        final BigDecimal all = decimal.add(records);//未兑换的+申请总额
        final double v1 = all.doubleValue();
        final double v2 = score.doubleValue();
        if(v1 > v2){
          return ToolClient.createJsonFail("本次申请积分和待兑换积分总值已超出总额");
        }
      }
      final HashMap<String,Object> map = apiUserBankDao.queryById(loginId);
      if(map == null){
        return ToolClient.createJsonFail("请先填写申请收款信息");
      }
      final Long outId = new IdBuilder().getId121L();
      final HashMap<String,Object> cash_log = new HashMap<>(7);
      cash_log.put("kid",new IdBuilder().getId121L());
      cash_log.put("user_id",loginId);
      cash_log.put("real_name",map.getOrDefault("real_name",null));
      cash_log.put("id_card",map.getOrDefault("id_card",null));
      cash_log.put("code",map.get("bank_code"));
      cash_log.put("out_id",outId);
      cash_log.put("bank_name",map.getOrDefault("bank_name",null));

      final PageFormData outRecord = new PageFormData();
      outRecord.put("kid",outId);
      outRecord.put("user_id",loginId);
      outRecord.put("total",decimal);
      return ToolClient.executeRows(apiUserDao.addUserAccountOut(outRecord,cash_log));
    },taskExecutor).join();
  }

  public String getReferrerScoreList(final HttpServletRequest request){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request,"userId");
      if(formData == null) return ToolClient.jsonValidateField();
      formData.put("loginId",loginId);
      return ToolClient.jsonPage(apiUserDao.getReferrerScoreList(formData));
    },taskExecutor).join();
  }

  public String getMyGroupIncome(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request);
      if(formData == null || formData.get("userId") == null) {
        formData.put("userId",loginId);
      }
      return ToolClient.jsonPage(apiUserDao.getMyGroupIncome(formData));
    },taskExecutor).join();
  }

  public String getMyGroupArea(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      HashMap<String, Object> partnerInfo = new HashMap<String,Object>(4);
      Long[] userIds = new Long[2];
      final Long loginIdL = Long.valueOf(loginId);
      partnerInfo = apiUserDao.getPartnerInfo(loginIdL);
      if(partnerInfo == null){
        return ToolClient.createJsonFail("代理不存在,刷新重试");
      } else if (partnerInfo.get("type").equals(3)) {
        return ToolClient.createJsonFail("请勿传入区级代理");
      }
      userIds[0] = loginIdL;
      final PageFormData formData = new PageFormData(request);
      if(formData != null) {
        final Long userIdL = formData.getLong("userId");
        if(userIdL != null) {
          partnerInfo = apiUserDao.getPartnerInfo(userIdL);
          if(partnerInfo == null){
            return ToolClient.createJsonFail("代理不存在,刷新重试");
          } else if (partnerInfo.get("type").equals(3)) {
            return ToolClient.createJsonFail("请勿传入区级代理");
          }
          userIds[1] = userIdL;
        };
        final Long cityIdL = formData.getLong("cityId");
        if(cityIdL != null){
          partnerInfo.put("type",2);
          partnerInfo.put("city_id",cityIdL);
        }
      }
      partnerInfo.put("userIds",userIds);
      return ToolClient.jsonPage(apiUserDao.getMyGroupArea(partnerInfo));
    },taskExecutor).join();
  }

  public String getAreaStoreList(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request);
      if(formData == null || formData.get("userId") == null) {
        formData.put("userId",loginId);
      }
      final HashMap<String, Object> map = apiUserDao.getPartnerInfo(formData.getLong("userId"));
      if(map == null){
        return ToolClient.createJsonFail("代理不存在,刷新重试");
      } else if ((Integer) map.get("type") != 3) {
        return ToolClient.createJsonFail("请传入区级代理");
      }
      return ToolClient.jsonPage(apiUserDao.getAreaStoreList(formData));
    },taskExecutor).join();
  }

  public String getStoreList(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final String p_type = "type";
      final PageFormData formData = ToolClient.pageParamsApi(request,p_type);
      if(formData == null){
        return ToolClient.jsonValidateField();
      }
      formData.put("loginId",Long.parseLong(loginId));
      final Integer type = formData.getInteger(p_type);
      if(type == 8){
        formData.remove(p_type);
      }
      return ToolClient.jsonPage(apiUserDao.getStoreList(formData));
    },taskExecutor).join();
  }

  public String updateStoreStatus(final String type,final String kid,final String uid,final String userId){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      if(type == null || kid == null || uid == null || userId == null){
        return ToolClient.jsonValidateField();
      }
      switch (type){
        case "2":
        case "3":
          break;
        default:
          return ToolClient.jsonValidateField();
      }
      if(!loginId.equals(userId)){
        return ToolClient.createJsonFail("您不是区代,审核失败");
      }
      final long key = Long.parseLong(kid);
      final long userKey = Long.parseLong(uid);
      final Long preAudit = apiUserDao.getPreAudit(userKey);//查询是否是申请过门店
      if(preAudit != null){
        return ToolClient.createJsonFail("店主重复申请门店");
      }
      //验证是否是代理商
      final boolean proxyUser = apiUserDao.getProxyUser(userKey);
      if(proxyUser){
        return ToolClient.createJsonFail("门店的店主已是代理商");
      }
      final String storeCode = apiUserDao.getStoreCode(key);
      final PageFormData formData = new PageFormData();
      formData.put("kid",key);
      formData.put("type",Integer.parseInt(type));
      if(storeCode != null){
        formData.put("invitation_code",storeCode);
        formData.put("user_key",userKey);
        return ToolClient.executeRows(apiUserDao.updateStoreCode(formData));
      }
      return ToolClient.executeRows(apiUserDao.updateStoreStatus(formData));
    },taskExecutor).join();
  }

  public String getStoreInfo(final String kid,final String userId){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      if(kid == null || userId == null){
        return ToolClient.jsonValidateField();
      }
      if(!loginId.equals(userId)){
        return ToolClient.jsonCode198("您不是区代,暂无权限操作");
      }
      return ToolClient.queryJson(apiUserDao.getStoreInfo(Long.parseLong(kid)));
    },taskExecutor).join();
  }

  public String getIntegralInfo(final HttpServletRequest request){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request,"type");
      if(formData == null){
        return ToolClient.jsonValidateField();
      }
      formData.put("loginId",Long.parseLong(loginId));
      return ToolClient.jsonPage(apiUserDao.getIntegralInfo(formData));
    },taskExecutor).join();
  }

  /**
   * 根据给定时间戳获取年、月、日、当天最开始的时间和最后的时间
   * @param timestamp 时间戳，单位为秒
   * @param type 返回类型，1为年，2为月，3为日
   * @return 指定类型最开始的时间戳和最后的时间戳
  */
  private HashMap<String,Long> getFirstAndLastTimestamp(final long timestamp,final int type) {
    final LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneOffset.of("+8"));
    final HashMap<String, Long> map = new HashMap<>();
    final LocalDate localDate = dateTime.toLocalDate();
    switch (type) {
      case 1:
        final LocalDateTime startOfYear = dateTime.withDayOfYear(1).withHour(0).withMinute(0).withSecond(0);
        final LocalDateTime endOfYear = dateTime.withDayOfYear(localDate.lengthOfYear()).withHour(23).withMinute(59).withSecond(59);
        map.put("start", startOfYear.toEpochSecond(ZoneOffset.of("+8")));
        map.put("end", endOfYear.toEpochSecond(ZoneOffset.of("+8")));
        break;
      case 2:
        final LocalDateTime startOfMonth = dateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        final LocalDateTime endOfMonth = dateTime.withDayOfMonth(localDate.lengthOfMonth()).withHour(23).withMinute(59).withSecond(59);
        map.put("start", startOfMonth.toEpochSecond(ZoneOffset.of("+8")));
        map.put("end", endOfMonth.toEpochSecond(ZoneOffset.of("+8")));
        break;
      case 3:
        final LocalDateTime startOfDay = dateTime.withHour(0).withMinute(0).withSecond(0);
        final LocalDateTime endOfDay = dateTime.withHour(23).withMinute(59).withSecond(59);
        map.put("start", startOfDay.toEpochSecond(ZoneOffset.of("+8")));
        map.put("end", endOfDay.toEpochSecond(ZoneOffset.of("+8")));
        break;
      default:
        return null;
    }
    return map;
  }

  public String listIntegralInfo(final HttpServletRequest request){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      final PageFormData formData = ToolClient.pageParamsApi(request);
      if(formData == null) return ToolClient.jsonValidateField();
      formData.put("loginId",loginId);
      final Integer type = formData.getInteger("type");
      final Long timestamp = formData.getLong("timestamp");
      if (type != null && timestamp != null){
        final HashMap<String, Long> firstAndLastTimestamp = getFirstAndLastTimestamp(timestamp, type);
        if(firstAndLastTimestamp != null){
          formData.put("start",firstAndLastTimestamp.get("start"));
          formData.put("end",firstAndLastTimestamp.get("end"));
        }
      }
      return ToolClient.jsonPage(apiUserDao.listIntegralInfo(formData));
    },taskExecutor).join();
  }

  public String getIntegralDetails(final String type,final String value){
    final Long loginId = LocalUserId.getLong();
    return CompletableFuture.supplyAsync(()->{
      if(loginId == null){
        return ToolClient.accessLogin();
      }
      if(type == null || value == null){
        return ToolClient.jsonValidateField();
      }
      final long val = Long.parseLong(value);
      switch (type){//当category=1时值是user_out_record的kid；为2时是user_integral_buy的out_trade_no；为3时积分商城的订单编号
        case "1":
          return ToolClient.queryJson(apiUserDao.getOutRecord(val));
        case "2":
          return ToolClient.queryJson(apiUserDao.getIntegralBuy(val));
        case "3":
          return ToolClient.jsonValidateField("尚未实现");
        default:
          return ToolClient.jsonValidateField();
      }
    },taskExecutor).join();
  }
}